/* Copyright (C) 2012  Chris Mueller <ruunsmail@googlemail.com>
 *
 * This file is part of the Liquid Programming Language
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef LIQUID_SCANNER_H_
#define LIQUID_SCANNER_H_

#include "base.h"

G_BEGIN_DECLS

#define STRING_ESCAPE_SYMBOL '\\'

struct LqContext;

enum LqTOK {
    LQ_TOKEN_EXCLAMATION  	= '!',
    LQ_TOKEN_BAND               = '&',
    LQ_TOKEN_ROUNDLEFTBRACE     = '(',
    LQ_TOKEN_ROUNDRIGHTBRACE    = ')',
    LQ_TOKEN_MULTIPLY           = '*',
    LQ_TOKEN_PLUS               = '+',
    LQ_TOKEN_COMMA              = ',',
    LQ_TOKEN_MINUS              = '-',
    LQ_TOKEN_DOT                = '.',
    LQ_TOKEN_DIVIDE             = '/',
    LQ_TOKEN_COLON              = ':',
    LQ_TOKEN_SEMICOLON          = ';',
    LQ_TOKEN_LESS               = '<',
    LQ_TOKEN_ASSIGN             = '=',
    LQ_TOKEN_GREATER            = '>',
    LQ_TOKEN_SQUARELEFTBRACE    = '[',
    LQ_TOKEN_BACKSLASH		    = '\\',
    LQ_TOKEN_SQUARERIGHTBRACE   = ']',
    LQ_TOKEN_POWER              = '^',
    LQ_TOKEN_UNDERSCORE         = '_',
    LQ_TOKEN_CURVEDLEFTBRACE    = '{',
    LQ_TOKEN_PIPE               = '|',
    LQ_TOKEN_CURVEDRIGHTBRACE   = '}',
    LQ_TOKEN_BNOT               = '~',
    LQ_TOKEN_BOF,
    LQ_TOKEN_EOF,
    LQ_TOKEN_NEWLINE,
    LQ_TOKEN_ARRAYLEFTBRACE,   
    LQ_TOKEN_ARRAYRIGHTBRACE,
    LQ_TOKEN_DOUBLECOLON,
    LQ_TOKEN_DOUBLEPIPE,       
    LQ_TOKEN_DOUBLEEXCLAMATION,
    LQ_TOKEN_MODULO,
    LQ_TOKEN_CONCAT,
    LQ_TOKEN_REDUCE,
    LQ_TOKEN_EQUAL,
    LQ_TOKEN_NOTEQUAL,
    LQ_TOKEN_GREATEREQUAL,
    LQ_TOKEN_LESSEQUAL,
    LQ_TOKEN_ARROWRIGHT,
    LQ_TOKEN_ARROWLEFT,
    LQ_TOKEN_AND,
    LQ_TOKEN_OR,
    LQ_TOKEN_NOT,
    LQ_TOKEN_BXOR,
    LQ_TOKEN_BITSHIFTLEFT,
    LQ_TOKEN_BITSHIFTRIGHT,
    LQ_TOKEN_HEXNUMBER,
    LQ_TOKEN_DECNUMBER,
    LQ_TOKEN_BINNUMBER,
    LQ_TOKEN_OCTNUMBER,
    LQ_TOKEN_FLOATPOINT,
    LQ_TOKEN_STRING,
    LQ_TOKEN_RAWSTRING,
    LQ_TOKEN_CHARACTER,
    LQ_TOKEN_ATOM,
    LQ_TOKEN_IDENTIFIER,
    LQ_TOKEN_EXTIDENTIFIER,
    LQ_TOKEN_LET,
    LQ_TOKEN_IF,
    LQ_TOKEN_THEN,
    LQ_TOKEN_ELSE,
    LQ_TOKEN_MATCH,
    LQ_TOKEN_BY,
    LQ_TOKEN_MODULE,
    LQ_TOKEN_FUN
};

struct LqToken {
    enum LqTOK value;
    byte* text;
    int line;
};

const byte*             lq_tok_to_string(enum LqTOK token);
struct LqToken*         create_token(enum LqTOK value, const byte* text, size_t size, int line);

void                    lq_scanner_initialize(void);

struct LqToken		    lq_scanner_next(struct LqContext* scanner);
struct LqToken		    lq_scanner_peek(struct LqContext* scanner, size_t index);

int			            lq_scanner_line(struct LqContext* scanner);
enum LqTOK              lq_scanner_token(struct LqContext* scanner);
byte* 			        lq_scanner_string(struct LqContext* scanner);

G_END_DECLS


#endif // LIQUID_SCANNER_H_
